package com.redis.paihangbang.service;

import com.redis.paihangbang.entity.StudentScore;
import com.redis.paihangbang.mapper.StudentScoreMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class RankingService {

    private final StudentScoreMapper studentScoreMapper;
    private final StringRedisTemplate stringRedisTemplate;

    // 排行榜Redis键名
    private static final String RANKING_KEY = "student:ranking";

    // 更新学生成绩并更新排行榜
    public void updateScore(String studentId, String studentName, Integer score) {
        // 1. 更新数据库
        StudentScore studentScore = new StudentScore();
        studentScore.setStudentId(studentId);
        studentScore.setStudentName(studentName);
        studentScore.setScore(score);

        // 检查学生是否已存在
        StudentScore existing = studentScoreMapper.findByStudentId(studentId);
        if (existing != null) {
            studentScore.setId(existing.getId());
            studentScoreMapper.update(studentScore);
        } else {
            studentScoreMapper.insert(studentScore);
        }

        // 2. 更新Redis排行榜（StringRedisTemplate 避免 Object 序列化差异）
        stringRedisTemplate.opsForZSet().add(RANKING_KEY, studentId, score);
    }

    // 新增或更新学生（允许不传分数则默认为0）
    public void upsertStudent(String studentId, String studentName, Integer score) {
        updateScore(studentId, studentName, score == null ? 0 : score);
    }

    // 删除学生
    public boolean deleteStudent(String studentId) {
        StudentScore existing = studentScoreMapper.findByStudentId(studentId);
        if (existing == null) {
            return false;
        }
        int rows = studentScoreMapper.deleteByStudentId(studentId);
        stringRedisTemplate.opsForZSet().remove(RANKING_KEY, studentId);
        return rows > 0;
    }

    // 查询全部（按分数降序）
    public List<StudentScore> listAll() {
        return studentScoreMapper.findAllOrderByScoreDesc();
    }

    // 获取排行榜
    public List<StudentScore> getTopRanking(int topN) {
        ensureRankingCacheWarm();
        Set<String> studentIds = stringRedisTemplate.opsForZSet().reverseRange(RANKING_KEY, 0, topN - 1);
        if (studentIds == null || studentIds.isEmpty()) {
            return Collections.emptyList();
        }
        List<StudentScore> result = studentScoreMapper.findByStudentIds(new ArrayList<>(studentIds));
        Map<String, StudentScore> scoreMap = result.stream()
                .collect(Collectors.toMap(StudentScore::getStudentId, Function.identity()));
        return studentIds.stream().map(scoreMap::get).collect(Collectors.toList());
    }

    // 获取学生排名
    public Long getStudentRank(String studentId) {
        ensureRankingCacheWarm();
        Long rank = stringRedisTemplate.opsForZSet().reverseRank(RANKING_KEY, studentId);
        return rank != null ? rank + 1 : null; // Redis排名从0开始，我们显示从1开始
    }

    // 确保 Redis 缓存包含全量排行榜
    public void ensureRankingCacheWarm() {
        Long zsetSize = stringRedisTemplate.opsForZSet().size(RANKING_KEY);
        long total = studentScoreMapper.countAll();
        if (zsetSize != null && zsetSize == total && zsetSize > 0) {
            return; // 已经是全量
        }
        rebuildRankingCache();
    }

    // 重建全量排行榜缓存：清空并用 DB 全量按分数降序填充
    public void rebuildRankingCache() {
        List<StudentScore> all = studentScoreMapper.findAllOrderByScoreDesc();
        stringRedisTemplate.delete(RANKING_KEY);
        if (all == null || all.isEmpty()) {
            return;
        }
        all.forEach(s -> stringRedisTemplate.opsForZSet().add(RANKING_KEY, s.getStudentId(), s.getScore()));
    }
}
